package com.dreamlin.app.net

import com.dreamlin.app.base.model.BaseViewModel
import com.dreamlin.app.base.model.DialogBean
import com.dreamlin.app.common.exception.rxweaver.core.GlobalErrorTransformer
import com.dreamlin.app.common.exception.rxweaver.core.RetryConfig
import com.dreamlin.app.common.exception.rxweaver.core.Suppiler
import com.google.gson.JsonSyntaxException
import io.reactivex.Observable
import io.reactivex.ObservableTransformer
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.Consumer
import io.reactivex.functions.Function
import io.reactivex.schedulers.Schedulers
import org.json.JSONException
import java.net.ConnectException
import java.net.SocketTimeoutException
import kotlin.Exception

object RxHelper {
    @JvmStatic
    fun <T> applySchedulers(viewModel: BaseViewModel): ObservableTransformer<T, T> {
        return ObservableTransformer {
            it.subscribeOn(Schedulers.io())
                .doOnSubscribe { viewModel.setShow(DialogBean.getShowInstance()) }
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .doFinally {
                    viewModel.setShow(DialogBean.getHideInstance())
                }
        }
    }

    @JvmStatic
    fun <T> applySchedulersWithoutLoading(viewModel: BaseViewModel): ObservableTransformer<T, T> {
        return ObservableTransformer {
            it.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
        }
    }

    /* private fun <T> handleGlobalError(viewModel: BaseViewModel): GlobalErrorTransformer<T> {

         return GlobalErrorTransformer(

             // 通过onNext流中数据的状态进行操作
             { results ->
                 //                    switch (results.code) {
                 //                        case STATUS_REQUEST_FAIL:
                 //                            return Observable.error(new UniteException(tUnityBean.code, tUnityBean.message));
                 //                        case STATUS_CONNECT_FAIL:
                 //                            return Observable.error(new ConnectServerException(tUnityBean.code, tUnityBean.message));
                 //                        case STATUA_OK:
                 //                            return Observable.just(tUnityBean);
                 //
                 //                    }
                 Observable.just<T>(results)
             }
             ,

             // 通过onError中Throwable状态进行操作
             { error ->
                 //                    if (error instanceof ConnectServerException) {
                 //                        return Observable.error(new ConnectFailedAlertDialogException());
                 //                    }
                 Observable.error(error)
             },

             Function<Throwable, Any> { error ->
                 //                        if (error instanceof ConnectServerException) {
                 //                            return new RetryConfig(
                 //                                    new Suppiler<Single<Boolean>>() {
                 //                                        @Override
                 //                                        public Single<Boolean> call() {
                 //                                            return RxDialog.showErrorDialog((BaseActivity) mView, "ConnectServerException")
                 //                                                    .flatMap(new Function<Boolean, SingleSource<? extends Boolean>>() {
                 //                                                        @Override
                 //                                                        public SingleSource<? extends Boolean> apply(Boolean retry) throws Exception {
                 //                                                            return Single.just(retry);
                 //                                                        }
                 //                                                    });
                 //                                        }
                 //                                    });
                 //                        }

                 if (error is SocketTimeoutException) {
                     RetryConfig(1, 3000, // 最多重试1次，延迟3000ms
                         object : Suppiler<Single<Boolean>> {
                             override fun call(): Single<Boolean> {
                                 return Single.create { emitter -> emitter.onSuccess(true) }
                             }
                         }
                     )
                 } else RetryConfig()

 // 其它异常都不重试
             },

             Consumer<Throwable> { throwable ->
                 //确保这里是UI线程，可以直接处理全局异常
                 throwable.printStackTrace()
                 DialogBean.instance.isShow = false
                 viewModel.setShow(DialogBean.instance)
                 if (throwable is JSONException) {
                     viewModel.setError("数据解析异常")
                 } else if (throwable is ConnectException) {
                     //判断是无网络异常，还是服务器异常
                 } else if (throwable is SocketTimeoutException) {
                     viewModel.setError("服务器异常")
                     *//*} else if (throwable is UniteException) {

                        if (uniteException.getCode() === 201) {
                            viewModel.setError(uniteException.getMessage())
                        } else if (uniteException.getCode() === 202) {
                            viewModel.setError("服务器异常")
                        }*//*
                } else {

                }
            }
        )
    }*/

    fun <T> handleGlobalError(viewModel: BaseViewModel): GlobalErrorTransformer<SuperBean<T>> {
        return GlobalErrorTransformer(
            //onNext
            Function { results ->
                if (results is SuperBean<T>) {
                    when (results.code) {
                        200 -> Observable.just(results)
                        201 -> Observable.error(UnityException(201, results.message))
                        202 -> Observable.error(SocketTimeoutException("服务器连接异常"))
                        else -> Observable.error(Exception("unknownError"))
                    }
                } else Observable.just(results)
            },
            // 通过onError中Throwable状态进行操作
            Function { throwable ->
                when (throwable) {
                    is JsonSyntaxException -> {
                        Observable.error(throwable)
                    }
                    else -> {
                        Observable.error(throwable)
                    }
                }
            },
            // retry 拦截
            Function { error ->
                when (error) {
                    is SocketTimeoutException -> {
                        RetryConfig(1, 3000, // 最多重试1次，延迟3000ms
                            object : Suppiler<Single<Boolean>> {
                                override fun call(): Single<Boolean> {
                                    return Single.create { emitter -> emitter.onSuccess(true) }
                                }
                            }
                        )
                        /*if (error instanceof ConnectServerException) {
                   return new RetryConfig (
                           new Suppiler < Single < Boolean > > () {
                               @Override
                               public Single < Boolean > call () {
                                   return RxDialog.showErrorDialog(
                                       (BaseActivity) mView,
                                       "ConnectServerException"
                                   )
                                       .flatMap(
                                           new Function < Boolean,
                                           SingleSource < ? extends Boolean > >() {
                                               @Override
                                               public SingleSource <? extends Boolean> apply(Boolean retry) throws Exception {
                                               return Single.just(retry);
                                           }
                                           });
                               }
                           });
               }*/
                        // 其它异常都不重试
                    }
                    else -> {
                        RetryConfig()
                    }
                }

            },
            //处理全局异常
            Consumer { throwable ->
                //确保这里是UI线程，可以直接处理全局异常
                throwable.printStackTrace()
                viewModel.setShow(DialogBean.getHideInstance())
                when (throwable) {
                    is JSONException -> {
                        viewModel.setError("数据解析异常")
                    }
                    is ConnectException -> {
                        //判断是无网络异常，还是服务器异常
                        viewModel.setError("网络连接异常，请检查网络")
                    }
                    is SocketTimeoutException -> {
                        viewModel.setError("服务器连接异常")
                    }
                    is UnityException, is UnityIOException -> {
                        throwable.message?.let {
                            if (it != "操作成功")
                                viewModel.setError(it)
                        }
                    }
                    else -> {
                        throwable.message?.let { viewModel.setError("未知错误") }
                    }
                }
            })
    }

    @JvmStatic
    fun handleError(ex: Exception, viewModel: BaseViewModel) {
        when (ex) {
            is JSONException -> {
                viewModel.setError("数据解析异常")
            }
            is ConnectException -> {
                //判断是无网络异常，还是服务器异常
                viewModel.setError("网络连接异常，请检查网络")
            }
            is SocketTimeoutException -> {
                viewModel.setError("服务器连接异常")
            }
            is UnityException, is UnityIOException -> {
                ex.message?.let {
                    if (it != "操作成功")
                        viewModel.setError(it)
                }
            }
            else -> {
                ex.message?.let { viewModel.setError("未知错误") }
            }
        }
    }

    fun handleInnerError(superBean: SuperBean<*>): Unit = when (superBean.code) {
        200 -> {
            //成功，什么都不做
        }
        201 -> throw UnityException(201, superBean.message)
        202 -> throw SocketTimeoutException("服务器连接异常")
        else -> throw UnityException(201, "未知错误")
    }

}